package com.project.demo

import com.mongodb.MongoException
import com.mongodb.client.MongoClients
import jakarta.servlet.*
import jakarta.servlet.http.HttpServletRequest
import org.bson.Document
import org.springframework.core.annotation.Order
import org.springframework.stereotype.Component
import org.springframework.stereotype.Controller
import org.springframework.ui.Model
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RequestParam
import redis.clients.jedis.Jedis
import java.io.IOException
import java.math.BigInteger
import java.security.MessageDigest
import java.util.*


@Component
@Order(1)
class TransactionFilter : Filter {
    @Throws(IOException::class, ServletException::class)
    override fun doFilter(
            request: ServletRequest,
            response: ServletResponse?,
            chain: FilterChain) {
        val req: HttpServletRequest = request as HttpServletRequest
        println("Starting a transaction for req :"+ req.getRequestURI())
        chain.doFilter(request, response)
        println("Committing a transaction for req :"+ req.getRequestURI())
    } // other methods
}


@Controller
class Controller () {
    @RequestMapping("/")
    fun loginpage():String{
        return "login"
    }

    @RequestMapping("/adduserpage")
    fun adduserpage():String{
        return "adduser"
    }

    @PostMapping("/adduser")
    fun adduser(@RequestParam("user") user:String,@RequestParam("password") password:String):String{
        val mongoclient=MongoClients.create("mongodb://127.0.0.1:27017")
        val database=mongoclient.getDatabase("admin")
        val collection=database.getCollection("user")
        val md = MessageDigest.getInstance("SHA-256")
        val bigInt = BigInteger(1, md.digest(password.toByteArray(Charsets.UTF_8)))
        val hashedpwd=String.format("%032x", bigInt)
        val document=Document("user",user)
        document.append("hashedpwd",hashedpwd)
        collection.insertOne(document)
        mongoclient.close()
        return "redirect:/"
    }

    @PostMapping("/login")
    fun loginrequest(model:Model,@RequestParam("user") user:String,@RequestParam("password") password:String):String{
        val uuid=UUID.randomUUID().toString()
        val mongoclient=MongoClients.create("mongodb://127.0.0.1:27017")
        val database=mongoclient.getDatabase("admin")
        val collection=database.getCollection("user")
        val md = MessageDigest.getInstance("SHA-256")
        val bigInt = BigInteger(1, md.digest(password.toByteArray(Charsets.UTF_8)))
        val hashedpwd=String.format("%032x", bigInt)
        val document=Document("user",user)
        document.append("hashedpwd",hashedpwd)
        try{
        if (collection.find(document).first()!!.isNotEmpty()){
            val jedis=Jedis("127.0.0.1",6379)
            jedis.set(uuid,"")
            jedis.expire(uuid,360)
            jedis.close()
        }else{
            model.addAttribute("error","用户或密码出错")
            return "error"
        }
            }catch(e:NullPointerException){
            model.addAttribute("error","用户或密码出错")
            return "error"
            }
        mongoclient.close()
        return "redirect:/crudpage?token="+uuid
    }

    @RequestMapping("/crudpage")
    fun defaultpage(model:Model,@RequestParam("token") token:String):String{
        val jedis=Jedis("127.0.0.1",6379)
        if(!jedis.exists(token)) {
            jedis.close()
            model.addAttribute("error","登录过期")
            return "error"
        }
        jedis.close()
        try{
            val mongoclient=MongoClients.create("mongodb://127.0.0.1:27017")
            val database=mongoclient.getDatabase("admin")
            val collection=database.getCollection("x")
            val result=collection.find().toList()
            model.addAttribute("result",result)
            model.addAttribute("token",token)
            mongoclient.close()
        }catch(e:MongoException){
            println("error")
        }
        return "res"
    }

    @PostMapping("/operate")
    fun operate(model:Model,@RequestParam("a") a:String,@RequestParam("b") b:String,@RequestParam("c") c:String,@RequestParam("addOrDel") addOrDel:String,@RequestParam("token") token:String):String{
        val jedis=Jedis("127.0.0.1",6379)
        if(!jedis.exists(token)) {
            jedis.close()
            model.addAttribute("error","登录过期")
            return "error"
        }
        jedis.close()
        val mongoclient=MongoClients.create("mongodb://127.0.0.1:27017")
        val database=mongoclient.getDatabase("admin")
        val collection=database.getCollection("x")
        val document=Document("a",a)
        document.append("b",b)
        document.append("c",c)
        val session=mongoclient.startSession()
        session.startTransaction()
        when(addOrDel){
            "add"->{
                collection.insertOne(document)
                return "redirect:/crudpage?token="+token
            }
            "del"->{
                collection.findOneAndDelete(document)
                return "redirect:/crudpage?token="+token
            }
        }
        session.commitTransaction();
        mongoclient.close()
        return ""
    }
}